home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
v8n03.arc
/
PP803.ARC
/
QFN.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-01-18
|
9KB
|
218 lines
;----------------------------------------------------------------------
; QFN.ASM -- Qualify File Name, OS/2 Version
; Copyright (c) 1989 Ziff Communications Co.
; PC Magazine * Ray Duncan * Feb 14, 1989
;
; Call with: DS:SI = filename address, AX = length
;
; Returns: Carry = clear if filename OK
; DS:SI = qualified filename, AX = length
; or
; Carry = set if bad filename
;
; Registers other than DS:SI and AX are preserved.
;----------------------------------------------------------------------
.286
extrn DosChDir:far ; OS/2 API functions
extrn DosQCurDisk:far
extrn DosQCurDir:far
extrn DosSelectDisk:far
DGROUP group _DATA
_DATA segment word public 'DATA'
cdrive dw 0 ; current drive
cpath db '\',64 dup (0) ; current directory
cpsiz dw $-cpath-1
drvmap dd ? ; valid drive bitmap
ndrive dw 0 ; new drive
tbuff db 64 dup (0) ; target directory
qbuff db 'X:\' ; qualified pathname
db 64 dup (0)
qbsiz dw $-qbuff-3
fname dw ? ; filename address
flen dw ? ; filename length
_DATA ends
;----------------------------------------------------------------------
_TEXT segment word public 'CODE'
assume cs:_TEXT,ds:DGROUP
public qfn ; make visible to Linker
qfn proc near ; qualify file name
push bx ; save registers
push cx
push dx
push di
push es
mov flen,ax ; save length and
mov fname,si ; address of filename
mov ax,ds ; make DGROUP addressable
mov es,ax ; with ES register
; save current drive...
push ds ; receives drive ID
push offset DGROUP:cdrive
push ds ; receives valid drive bitmap
push offset DGROUP:drvmap
call DosQCurDisk ; transfer to OS/2
; save current directory...
push 0 ; drive ID = current
push ds ; receives directory path
push offset DGROUP:cpath+1
push ds ; contains buffer length
push offset DGROUP:cpsiz
call DosQCurDir ; transfer to OS/2
; did caller specify drive?
mov di,fname ; get address of name
mov cx,flen ; get length of name
cmp cx,2 ; if drive, length must be >= 2 chars.
jl qfn2 ; too short, no drive
cmp byte ptr [di+1],':' ; check for drive delimiter
jne qfn2 ; no delimiter, jump
mov al,[di] ; get ASCII drive code
or al,20h ; fold to lower case
sub al,'a'-1 ; convert it to binary
xor ah,ah
; now select new drive
push ax ; binary drive ID
call DosSelectDisk ; transfer to OS/2
or ax,ax ; was drive valid?
jz qfn1 ; jump, drive was OK
jmp qfn8 ; exit, drive not valid
qfn1: add di,2 ; bump pointer past drive
sub cx,2 ; and decrement length
qfn2: ; get current directory again for new drive...
push 0 ; drive ID = current
push ds ; receives directory path
push offset DGROUP:cpath+1
push ds ; contains buffer length
push offset DGROUP:cpsiz
call DosQCurDir ; transfer to OS/2
; scan off path if any...
push di ; save start of path
mov al,'\' ; path delimiter
qfn3: mov fname,di ; save path pointer
mov flen,cx ; save path length
jcxz qfn4 ; jump if none left
repne scasb ; any '\' left in path?
je qfn3 ; loop if '\' found
qfn4: pop si ; recover starting address of path portion
; copy path to local buffer and make it ASCIIZ...
mov di,offset DGROUP:tbuff
mov cx,fname ; calculate path length
sub cx,si
jz qfn6 ; jump, no path at all
cmp cx,1 ; root directory?
je qfn5 ; jump if root
dec cx ; else discard last '\'
qfn5: rep movsb ; transfer path and
xor al,al ; append null byte
stosb
; select target directory...
push ds ; directory path address
push offset DGROUP:tbuff
push 0 ; DWORD reserved
push 0
call DosChDir ; transfer to OS/2
or ax,ax ; directory valid?
jnz qfn8 ; jump, no such directory
; build up full pathname...get current drive
qfn6:
push ds ; receives drive ID
push offset DGROUP:ndrive
push ds ; receives valid drive bitmap
push offset DGROUP:drvmap
call DosQCurDisk ; transfer to OS/2
mov ax,ndrive ; convert binary drive code
add ax,'a'-1 ; to ASCII drive identifier
mov qbuff,al
; get current directory
push 0 ; drive ID = current
push ds ; receives directory path
push offset DGROUP:qbuff+3
push ds ; contains buffer length
push offset DGROUP:qbsiz
call DosQCurDir ; transfer to OS/2
or ax,ax ; operation successful?
jnz qfn8 ; no, return error
; point to path component
mov di,offset DGROUP:qbuff+3
cmp byte ptr [di],0 ; is current directory the root directory?
je qfn7 ; yes, jump
xor al,al ; scan for null byte at
mov cx,-1 ; end of path name
repne scasb ; and append backslash
mov byte ptr [di-1],'\'
qfn7: ; now append filename
; to drive and path...
mov si,fname ; filename address
cmp byte ptr [si],'.'
je qfn8 ; exit if directory alias
mov cx,flen ; filename length
rep movsb ; copy it
mov si,offset DGROUP:qbuff ; set DS:SI = address
mov ax,di ; and AX = length of
sub ax,si ; fully qualified filename
call makelc ; fold filename to lower case to make it pretty
clc ; set Carry = false to indicate success and
jmp qfn9 ; go to common exit point
qfn8: ; come here if any error detected...
stc ; set Carry = true to indicate error
qfn9: pushf ; save Carry flag
push ax ; save final length
; restore original directory
push ds ; address of directory path
push offset DGROUP:cpath
push 0 ; DWORD reserved
push 0
call DosChDir ; transfer to OS/2
; restore original drive
push cdrive ; binary drive ID
call DosSelectDisk
pop ax ; restore length
popf ; and Carry flag
pop es ; restore other affected
pop di ; registers
pop dx
pop cx
pop bx
ret ; back to caller
qfn endp
;----------------------------------------------------------------------
makelc proc near ; string -> lower case, DS:SI = address, AX = length
push bx ; save BX contents
xor bx,bx ; BX will be pointer
mlc1: ; change A-Z to a-z
cmp byte ptr [bx+si],'A'
jb mlc2
cmp byte ptr [bx+si],'Z'
ja mlc2
or byte ptr [bx+si],20h
mlc2: inc bx ; advance through string
cmp bx,ax ; done with string yet?
jne mlc1 ; no, check next char.
pop bx ; restore BX and
ret ; return to caller
makelc endp
_TEXT ends
end